//-
// ==========================================================================
// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All 
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related 
// material (collectively the "Data") in these files contain unpublished 
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its 
// licensors, which is protected by U.S. and Canadian federal copyright 
// law and by international treaties.
//
// The Data is provided for use exclusively by You. You have the right 
// to use, modify, and incorporate this Data into other products for 
// purposes authorized by the Autodesk software license agreement, 
// without fee.
//
// The copyright notices in the Software and this entire statement, 
// including the above license grant, this restriction and the 
// following disclaimer, must be included in all copies of the 
// Software, in whole or in part, and all derivative works of 
// the Software, unless such copies or derivative works are solely 
// in the form of machine-executable object code generated by a 
// source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. 
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED 
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF 
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 
// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR 
// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS 
// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, 
// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK 
// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY 
// OR PROBABILITY OF SUCH DAMAGES.
//
// ==========================================================================
//+

#include <maya/MPxCommand.h>
#include <maya/MStatus.h>
#include <maya/MArgList.h>
#include <maya/MFnPlugin.h>
#include <maya/MObject.h>
#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MItSelectionList.h>
#include <maya/MSelectionList.h>
#include <maya/MString.h>
#include <maya/MPoint.h>

#include <maya/MItCurveCV.h>
#include <maya/MItSurfaceCV.h>
#include <maya/MItMeshVertex.h>

#include <maya/MIOStream.h>

class cvPos : public MPxCommand
{
public:
                cvPos();
    virtual     ~cvPos();

    MStatus     doIt ( const MArgList& args );
    MStatus     redoIt ();
    MStatus     undoIt ();
    bool        isUndoable() const;

    static      void* creator();

private:
    MPoint      point;
};

cvPos::cvPos() :
    point(0.0, 0.0, 0.0)
{
}

cvPos::~cvPos() {}

void* cvPos::creator()
{
    return new cvPos;
}

bool cvPos::isUndoable() const
{
    return true;
}

MStatus cvPos::undoIt()
{
    return MS::kSuccess;
}

MStatus cvPos::doIt( const MArgList& args )
{

    MString componentName;
	MSpace::Space transformSpace = MSpace::kWorld;

	for (unsigned int i = 0; i < args.length (); i++)
	{
		MString argStr;
		args.get (i, argStr);
		if (MString ("-l") == argStr || MString ("-local") == argStr)
			transformSpace = MSpace::kObject;
		else if (MString ("-w") == args.asString (i) ||
				 MString ("-world") == argStr)
			transformSpace = MSpace::kWorld;
		else
			componentName = argStr;
	}

    MObject     component;
    MDagPath    dagPath;

	if (!componentName.length ()) {
		MSelectionList activeList;

		MGlobal::getActiveSelectionList (activeList);

		MItSelectionList iter (activeList, MFn::kComponent);
		if (iter.isDone ())	{
			displayError ("No components selected");
			return MS::kFailure;
		} else {
			iter.getDagPath (dagPath, component);
			iter.next ();
			if (!iter.isDone ()) {
				displayError ("More than one component is selected");
				return MS::kFailure;
			}
		}
	} else {
		MSelectionList list;

		if (! list.add( componentName ) ) {
			componentName += ": no such component";
			displayError(componentName);
			return MS::kFailure; // no such component
		}
		MItSelectionList iter( list );
        iter.getDagPath( dagPath, component );
	}

	if (component.isNull()) {
		displayError("not a component");
		return MS::kFailure;
	}

	switch (component.apiType()) {
	case MFn::kCurveCVComponent:
		{
			MItCurveCV curveCVIter( dagPath, component );
			point = curveCVIter.position(transformSpace );
			curveCVIter.next();
			if (!curveCVIter.isDone()) {
				displayError ("More than one component is selected");
				return MS::kFailure;
			}
			break;
		}

	case MFn::kSurfaceCVComponent:
		{
			MItSurfaceCV surfCVIter( dagPath, component, true );
			point = surfCVIter.position(transformSpace );
			surfCVIter.next();
			if (!surfCVIter.isDone()) {
				displayError ("More than one component is selected");
				return MS::kFailure;
			}
			break;
		}

	case MFn::kMeshVertComponent:
		{
			MItMeshVertex vertexIter( dagPath, component );
			point = vertexIter.position(transformSpace );
			vertexIter.next();
			if (!vertexIter.isDone()) {
				displayError ("More than one component is selected");
				return MS::kFailure;
			}
			break;
		}

	default:
		cerr << "Selected unsupported type: (" << component.apiType()
			 << "): " << component.apiTypeStr() << endl;
	}

    return redoIt();
}

MStatus cvPos::redoIt()
{
    clearResult();
    appendToResult( point.x );
    appendToResult( point.y );
    appendToResult( point.z );

    return MS::kSuccess;
}

MStatus initializePlugin( MObject obj )
{
	MStatus   status;
    MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");

    status = plugin.registerCommand( "cvPos", cvPos::creator );
	if (!status) {
		status.perror("registerCommand");
		return status;
	}

    return status;
}

MStatus uninitializePlugin( MObject obj )
{
	MStatus   status;
    MFnPlugin plugin( obj );

    status = plugin.deregisterCommand( "cvPos" );
	if (!status) {
		status.perror("deregisterCommand");
		return status;
	}

    return status;
}
